use crate::define::*;
use async_trait::async_trait;
use log::debug;
use windows::{
    core::HSTRING,
    Devices::Enumeration::DeviceInformation,
    Win32::Devices::Usb::GUID_DEVINTERFACE_USB_DEVICE,
};
use crate::os::windows::device::OsDevice;


pub struct Manager {
    asq_usb: String,
}

impl Manager {
    pub fn new() -> Self {
        debug!("windows manager");
        let asq_usb = format!("System.Devices.InterfaceClassGuid:=\"{{{:?}}}\" \
        AND System.Devices.InterfaceEnabled:=System.StructuredQueryType.Boolean#True", GUID_DEVINTERFACE_USB_DEVICE);
        let one = Self {
            asq_usb
        };
        one
    }
}

#[async_trait]
impl OsManager for Manager {

  async fn device_find(&self, vid: Option<u64>, pid: Option<u64>) ->MResult<Vec<Box<dyn Device>>> {

    let aqs_filter = HSTRING::from(&self.asq_usb);
    let find_all = DeviceInformation::FindAllAsyncAqsFilter(&aqs_filter)?.await?;
    let mut out: Vec<Box<dyn Device>> = vec![];
    for i in 0..find_all.Size()? {
        let info = find_all.GetAt(i)?;
        let device = OsDevice::try_from(info)?;
        match vid {
            None => {}
            Some(want) => {
                if want != device.get_vid() { continue }
            }
        }
        match pid {
            None => {}
            Some(want) => {
                if want != device.get_pid() { continue }
            }
        }

        let device_ptr = Box::new(device);
        out.push(device_ptr);
    }
    Ok(out)



    }
}